package itb.fhv.sa.pipesfilters;

public class PageFilter extends Filter {

	private int m_pageLength;
	private int m_lines; // current number of lines
	private StringBuffer m_page;


	public PageFilter(Pipe neighbour, int pageLength) {
		super(neighbour);
		m_neighbour1 = neighbour;
		m_pageLength = pageLength;
		m_lines = 0;
		m_page = new StringBuffer();
	}


	/**
	 * Reads the next Line from the pipeline and appends it to the current Page.
	 * 
	 * @return A Page object.
	 */
	@Override
	public PLOutput read() {
		Line line = (Line) m_neighbour1.read();
		Page page = null;

		// read lines until the page length is reached
		while (line != null && m_lines < m_pageLength
				&& !line.getContent().contains("\1")) {			
			m_page.append(line.getContent() + "\r\n");
			line = (Line) m_neighbour1.read();
			m_lines++;
		}

		if (line != null) { // end the page
			m_page.append(line.getContent());

			// detect end of data
			if (!line.getContent().contains("\1")) {
				m_page.append("\r\n");
			}
			
			page = new Page(new String(m_page));
			m_lines = 0;
			m_page = new StringBuffer();
		}

		return page;
	}


	/**
	 * Writes provided Line objects to the current Page.
	 */
	@Override
	public boolean write(PLOutput plo) {
		boolean written = false;

		if (m_lines == m_pageLength) {
			m_page.append("\r\n");

			// try to write until successful
			while (written == false) {
				written = m_neighbour1.write(new Page(new String(m_page)));
			}

			written = false;
			m_lines = 0;
			m_page = new StringBuffer();
		}

		// append the Line to the current Page
		m_page.append(((Line) plo).getContent());
		m_page.append("\r\n");
		m_lines++;

		return false;
	}


	public void setPageLength(int pageLength) {
		m_pageLength = pageLength;
	}


	/**
	 * Flushes the pipeline.
	 */
	@Override
	public void flush() {
		boolean written = false;
		m_page.append("\n");
		Page page = new Page(new String(m_page));

		while (written == false) {
			written = m_neighbour1.write(page);
		}

		written = false;
		m_lines = 0;
		m_page = new StringBuffer();
		m_neighbour1.flush();
	}


}
